package com.wkbb.sports.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.*;
import com.wkbb.common.handler.JsonUtil;
import com.wkbb.common.utils.StringUtil;
import com.wkbb.sports.dto.*;
import com.wkbb.sports.enums.SportsMarkTypeEnum;
import com.wkbb.sports.enums.SportsRuleTypeEnum;
import com.wkbb.sports.enums.SportsStateEnum;
import com.wkbb.sports.feign.BasicFeignService;
import com.wkbb.sports.mapper.*;
import com.wkbb.sports.model.*;
import com.wkbb.sports.service.PhysicalService;
import com.wkbb.sports.service.SettingService;
import com.wkbb.sports.utils.ExcelFieldUtil;
import com.wkbb.sports.utils.SportsUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author dengjy
 * 创建时间：2021-01-20 15:53
 */
@Service
@Slf4j
public class PhysicalServiceImpl extends BaseServiceImpl<HlifePhysical> implements PhysicalService {

    @Autowired
    private HlifePhysicalMapper physicalMapper;

    @Autowired
    private HlifePhysicalTargetMapper physicalTargetMapper;

    @Autowired
    private HlifePhysicalRuleItemMapper physicalRuleItemMapper;

    @Autowired
    private HlifePhysicalRuleMapper physicalRuleMapper;

    @Autowired
    private HlifePhysicalRulePlusesMapper physicalRulePlusesMapper;

    @Autowired
    private HlifeAchievementMapper achievementMapper;

    @Autowired
    private SettingService settingService;
    
    
    @Autowired
    private BasicFeignService basicFeignService;

    public void setMapper(HlifePhysicalMapper mapper) {
        super.setMapper(mapper);
    }

    @Override
    public PageInfo<PhysicalDto> getPhysicalPageList(Map<String, Object> params, Integer pageNo, Integer pageSize) {
        if (pageNo == null || pageSize == null) {
            return null;
        }
        //条件不为空时,按条件找出符合条件的项目id
        if (!StringUtils.isEmpty(params.get("gradeId"))) {
            List<HlifePhysicalRule> rule = physicalRuleMapper.getListByMapParams(params);
            HashSet<Long> physicalIds = new HashSet<>();
            if (rule != null && rule.size() > 0) {
                for (HlifePhysicalRule physicalRule : rule) {
                    physicalIds.add(physicalRule.getPhysicalId());
                }
                params.put("physicalIds", physicalIds);
            } else {
                return new PageInfo<PhysicalDto>();
            }
        }
        Page<PhysicalDto> page = PageHelper.startPage(pageNo, pageSize, true);
        //查出体质项目信息
        List<PhysicalDto> physicalPageList = physicalMapper.getPhysicalPageList(params);
        for (int i = 0; i < physicalPageList.size(); i++) {
            List<PhysicalRuleDto> ruleDtoList = new ArrayList<>();
            PhysicalDto physicalDto = physicalPageList.get(i);
            params.put("physicalId", physicalDto.getId());
            List<PhysicalTargetDto> targeDtotList = new ArrayList<>();
            //指标
            List<HlifePhysicalTarget> targetList = physicalTargetMapper.getListByMapParams(params);
            for (HlifePhysicalTarget physicalTarget : targetList) {
                PhysicalTargetDto targetDto = new PhysicalTargetDto();
                targetDto.setPhysicalId(physicalTarget.getPhysicalId());
                targetDto.setDictValue(physicalTarget.getDictValue());
                targeDtotList.add(targetDto);
            }

            physicalDto.setTargetList(targeDtotList);
            List<HlifePhysicalRule> ruleList = physicalRuleMapper.getListByMapParams(params);
            for (HlifePhysicalRule physicalRule : ruleList) {
                List<PhysicalRuleItemDto> itemDtoList = new ArrayList<>();
                PhysicalRuleDto physicalRuleDto = new PhysicalRuleDto();
                physicalRuleDto.setId(physicalRule.getId());
                physicalRuleDto.setGradeId(physicalRule.getGradeId());
                physicalRuleDto.setGradeName(physicalRule.getGradeName());
                physicalRuleDto.setRuleType(physicalRule.getRuleType());
                physicalRuleDto.setSex(physicalRule.getSex());
                physicalRuleDto.setOrgId(physicalRule.getOrgId());
                params.put("ruleId", physicalRuleDto.getId());
                List<HlifePhysicalRuleItem> itemList = physicalRuleItemMapper.getListByMapParams(params);
                for (HlifePhysicalRuleItem physicalRuleItem : itemList) {
                    PhysicalRuleItemDto itemDto = new PhysicalRuleItemDto();
                    itemDto.setMax(physicalRuleItem.getMax());
                    itemDto.setComment(physicalRuleItem.getComment());
                    itemDto.setMin(physicalRuleItem.getMin());
                    itemDto.setName(physicalRuleItem.getName());
                    itemDto.setScoreValue(physicalRuleItem.getScoreValue());
                    itemDto.setScore(physicalRuleItem.getScore());
                    itemDto.setRuleId(physicalRuleItem.getRuleId());
                    itemDtoList.add(itemDto);
                    physicalRuleDto.setItemDtoList(itemDtoList);
                }
                ruleDtoList.add(physicalRuleDto);
            }
            physicalDto.setRuleList(ruleDtoList);
        }
        PageInfo<PhysicalDto> pageInfo = new PageInfo<PhysicalDto>(physicalPageList);
        pageInfo.setTotal(page.getTotal());
        return pageInfo;
    }

    /**
     * 删除体质项目
     *
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultDTO<?> delPhysical(Map<String, Object> params) {
        HlifePhysical physical = physicalMapper.getByMapParams(params);
        //只读不能删除
        if (physical.getReadStatus() == 1) {
            return new ResultDTO<>(false, "200", "只读不能删除");
        }
        //type考试类型2为体质类型
        params.put("type", 2);
        List<HlifeAchievement> achievementProjectList = achievementMapper.getAchivementByProjectId(params);
        if (achievementProjectList == null || achievementProjectList.size() == 0) {
            List<HlifePhysicalRule> ruleList = physicalRuleMapper.getListByMapParams(params);
            if (ruleList != null && ruleList.size() > 0) {
                physicalRuleItemMapper.delPhysicalRuleItem(ruleList);
            }
            physicalRuleMapper.delPhysicalRule(params);
            physicalTargetMapper.delPhysicalTarget(params);
            physicalMapper.delPhysical(params);
            return new ResultDTO<>(true);
        } else {
            return new ResultDTO<>(false, "200", "项目已有分数不能删除");
        }
    }

    /**
     * 启用禁用体质项目
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultDTO<?> updatePhysicalState(Long physicalId,Integer state) {
        HlifePhysical physical = physicalMapper.getByPrimaryKey(physicalId);
        if(null!=physical) {
            if (state.equals(SportsStateEnum.ENABLE.getValue())) {
                if (physical.getMarkType().equals(SportsMarkTypeEnum.NATIONAL.getValue().byteValue())) {
                    //国家标准每个项目只能有一条规则启用状态
                    Map<String, Object> params = new HashMap<>();
                    params.put("projectKind", physical.getProjectKind());
                    params.put("markType", physical.getMarkType());
                    params.put("modelType", physical.getModelType());
                    params.put("state", SportsStateEnum.ENABLE.getValue());

                    List<HlifePhysical> physicalList = physicalMapper.getListByMapParams(params);
                    if (!physicalList.isEmpty()) {
                        return new ResultDTO<>(false, "200", "该项目已存在启用状态的国家标准");
                    }
                } else if (physical.getMarkType().equals(SportsMarkTypeEnum.DISTRICT.getValue().byteValue())) {
                    {
                        //地方标准每个项目每个地区只能有一条规则启用状态
                        Map<String, Object> params = new HashMap<>();
                        params.put("projectKind", physical.getProjectKind());
                        params.put("markType", physical.getMarkType());
                        params.put("modelType", physical.getModelType());
                        params.put("provinceId", physical.getProvinceId());
                        params.put("cityId", physical.getCityId());
                        params.put("state", SportsStateEnum.ENABLE.getValue());

                        List<HlifePhysical> physicalList = physicalMapper.getListByMapParams(params);
                        if (!physicalList.isEmpty()) {
                            return new ResultDTO<>(false, "200", "该项目已存在启用状态的地方标准");
                        }
                    }
                }
            }

            //修改状态
            physical.setState(state.byteValue());
            physicalMapper.updatePhysicalState(physical);
        }

        return new ResultDTO<>(true);
    }

    /**
     * 增加体质项目
     * @param physicalDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultDTO<?> addPhysical(PhysicalDto physicalDto) {
        Map<String, Object> params = new HashMap<>();
        params.put("orgId", physicalDto.getOrgId());
        params.put("name", physicalDto.getName());
        HlifePhysical checkPhysicalName = checkName(params);
        if (checkPhysicalName != null) {
            return new ResultDTO<>(false, "200", "体质项目名称已存在");
        }
        //插入体质项目信息
        HlifePhysical physical = new HlifePhysical();
        physical.setName(physicalDto.getName());                       //项目名称
        physical.setMarkType(physicalDto.getMarkType());               //标准类型
        physical.setModelType(physicalDto.getModelType());             //模式
        physical.setProjectKind(physicalDto.getProjectKind());         //类型
        physical.setOrgId(physicalDto.getOrgId());                     //学校id
        physical.setProvince(physicalDto.getProvince());           //省份id
        physical.setCity(physicalDto.getCity());                   //城市id
        physical.setProvinceId(physicalDto.getProvinceId());           //省份id
        physical.setCityId(physicalDto.getCityId());                   //城市id
        physical.setUnit(physicalDto.getUnit());                       //单位
        physical.setRemark(physicalDto.getRemark());                   //项目内容
        physical.setStatus((byte)1);                                  //项目状态
        physicalMapper.insert(physical);

        //插入年级规则和得分规则以及加分项
        insertRules(physicalDto.getRuleList(), physical);

        //插入体质项目考察点列表
        if (physicalDto.getTargetList() != null) {
            List<HlifePhysicalTarget> targetList = new ArrayList<>();
            for (PhysicalTargetDto targetDto : physicalDto.getTargetList()) {
                HlifePhysicalTarget physicalTarget = new HlifePhysicalTarget();
                physicalTarget.setTargetId(targetDto.getTargetId());
                physicalTarget.setPhysicalId(physical.getId());
                targetList.add(physicalTarget);
            }
            physicalTargetMapper.insertBatch(targetList);
        }

        return new ResultDTO<>(true);
    }


    /**
     * 修改体质
     * @param physicalDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultDTO<?> updatePhysical(PhysicalDto physicalDto) {
        Map<String, Object> params = new HashMap<>();
        params.put("orgId", physicalDto.getOrgId());
        params.put("id", physicalDto.getId());
        //检查提交的是否是同一个项目名称
        HlifePhysical hlifePhysical = physicalMapper.getByMapParams(params);
        if (hlifePhysical.getId().longValue() == physicalDto.getId().longValue()) {
            //只读只可以修改年级
            if (hlifePhysical.getReadStatus() == 1) {
                for (PhysicalRuleDto physicalRuleDto : physicalDto.getRuleList()) {
                    if (physicalRuleDto.getId() == null) {
                        log.info("规年级则id为null");
                        return new ResultDTO<>(false, "200", "参数缺失");
                    }
                    HlifePhysicalRule rule = new HlifePhysicalRule();
                    rule.setGradeName(physicalRuleDto.getGradeName());
                    rule.setGradeId(physicalRuleDto.getGradeId());
                    rule.setId(physicalRuleDto.getId());
                    physicalRuleMapper.update(rule);
                }
                return new ResultDTO<>(true);
            }
            Map<String, Object> param = new HashMap<>();
            param.put("orgId", physicalDto.getOrgId());
            param.put("name", physicalDto.getName());
            param.put("id", physicalDto.getId());
            HlifePhysical checkPhysicalName = checkName(param);
            if (checkPhysicalName != null) {
                return new ResultDTO<>(false, "200", "体质项目名称已存在");
            }
            params.put("physicalId", physicalDto.getId());
            List<HlifePhysicalRule> ruleList = physicalRuleMapper.getListByMapParams(params);
            if (ruleList != null && ruleList.size() > 0) {
                physicalRuleItemMapper.delPhysicalRuleItem(ruleList);        //删除得分规则
                physicalRulePlusesMapper.delPhysicalRulePluses(ruleList);        //删除加分规则
            }

            physicalRuleMapper.delPhysicalRule(params);                     //删除年级规则
            physicalTargetMapper.delPhysicalTarget(params);                 //删除指标
            HlifePhysical physical = new HlifePhysical();
            physical.setName(physicalDto.getName());                       //项目名称
            physical.setOrgId(physicalDto.getOrgId());                     //学校id
            physical.setId(physicalDto.getId());
            physical.setUnit(physicalDto.getUnit());                       //单位
            physical.setRemark(physicalDto.getRemark());                   //项目内容
            physical.setMarkType(physicalDto.getMarkType());               //标准类型
            physical.setModelType(physicalDto.getModelType());             //模式
            physical.setProjectKind(physicalDto.getProjectKind());         //类型
            physical.setProvinceId(physicalDto.getProvinceId());           //省份id
            physical.setCityId(physicalDto.getCityId());                   //城市id
            physicalMapper.update(physical);                                //修改体质项目
            //插入年级规则和得分规则以及加分项
            insertRules(physicalDto.getRuleList(), physical);

            //插入指标列表
            if (physicalDto.getTargetList() != null) {
                List<HlifePhysicalTarget> targetList = new ArrayList<>();
                for (PhysicalTargetDto targetDto : physicalDto.getTargetList()) {
                    HlifePhysicalTarget physicalTarget = new HlifePhysicalTarget();
                    physicalTarget.setTargetId(targetDto.getTargetId());
                    physicalTarget.setPhysicalId(physical.getId());
                    targetList.add(physicalTarget);
                }
                physicalTargetMapper.insertBatch(targetList);
            }
        } else {
            return new ResultDTO<>(ErrorCode.AREA_TEMPLATE_EXIST);
        }
        return new ResultDTO<>(true);
    }

    /**
     * 详情
     * @param params
     * @return
     */
    @Override
    public ResultDTO<?> getPhysicalById(Map<String, Object> params) {
        //查出体质项目信息
        List<PhysicalDto> physicalDtoList = physicalMapper.getPhysicalById(params);
        for (int i = 0; i < physicalDtoList.size(); i++) {
            List<PhysicalRuleDto> ruleDtoList = new ArrayList<>();
            PhysicalDto physicalDto = physicalDtoList.get(i);
            params.put("physicalId", physicalDto.getId());
            List<PhysicalTargetDto> targeDtotList = new ArrayList<>();
            //指标
            List<HlifePhysicalTarget> targetList = physicalTargetMapper.getListByMapParams(params);
            for (HlifePhysicalTarget physicalTarget : targetList) {
                PhysicalTargetDto targetDto = new PhysicalTargetDto();
                targetDto.setPhysicalId(physicalTarget.getPhysicalId());
                targetDto.setDictValue(physicalTarget.getDictValue());
                targeDtotList.add(targetDto);
            }
            physicalDto.setTargetList(targeDtotList);
            List<HlifePhysicalRule> ruleList = physicalRuleMapper.getListByMapParams(params);
            for (HlifePhysicalRule physicalRule : ruleList) {
                List<PhysicalRuleItemDto> itemDtoList = new ArrayList<>();
                PhysicalRuleDto physicalRuleDto = new PhysicalRuleDto();
                physicalRuleDto.setId(physicalRule.getId());
                physicalRuleDto.setGradeId(physicalRule.getGradeId());
                physicalRuleDto.setWeight(physicalRule.getWeight());
                physicalRuleDto.setGradeName(physicalRule.getGradeName());
                physicalRuleDto.setRuleType(physicalRule.getRuleType());
                physicalRuleDto.setSex(physicalRule.getSex());
                physicalRuleDto.setOrgId(physicalRule.getOrgId());
                params.put("ruleId", physicalRuleDto.getId());
                List<HlifePhysicalRuleItem> itemList = physicalRuleItemMapper.getListByMapParams(params);
                for (HlifePhysicalRuleItem physicalRuleItem : itemList) {
                    PhysicalRuleItemDto itemDto = new PhysicalRuleItemDto();
                    itemDto.setMax(physicalRuleItem.getMax());
                    itemDto.setComment(physicalRuleItem.getComment());
                    itemDto.setMin(physicalRuleItem.getMin());
                    itemDto.setName(physicalRuleItem.getName());
                    itemDto.setScoreValue(physicalRuleItem.getScoreValue());
                    itemDto.setScore(physicalRuleItem.getScore());
                    itemDto.setRuleId(physicalRuleItem.getRuleId());
                    itemDtoList.add(itemDto);
                    physicalRuleDto.setItemDtoList(itemDtoList);
                }
                /**
                 * 额外加分
                 */
                List<PhysicalRulePlusesDto> plusesDtList = new ArrayList<>();
                List<HlifePhysicalRulePluses> plusesList = physicalRulePlusesMapper.getListByMapParams(params);
                for (HlifePhysicalRulePluses rulePluses : plusesList) {
                    PhysicalRulePlusesDto pluses = new PhysicalRulePlusesDto();
                    pluses.setMin(rulePluses.getMin());
                    pluses.setMax(rulePluses.getMax());
                    pluses.setBonusValue(rulePluses.getBonusValue());
                    pluses.setScore(rulePluses.getScore());
                    pluses.setRuleId(rulePluses.getRuleId());
                    plusesDtList.add(pluses);
                    physicalRuleDto.setPlusesList(plusesDtList);
                }
                ruleDtoList.add(physicalRuleDto);
            }
            physicalDto.setRuleList(ruleDtoList);
        }
        return new ResultDTO<>(physicalDtoList);
    }


    /**
     * 检查名字唯一
     * @param params
     * @return
     */
    public HlifePhysical checkName(Map<String, Object> params) {
        return physicalMapper.checkName(params);
    }

    @Transactional
    @Override
    public void copyRule(Long projectId,long sourceOrg, long targetOrg) throws Exception {

        List<HlifePhysical> physicalList = null;

        if(null==projectId) {
            physicalList = physicalMapper.getPhysicalListByOrg(sourceOrg);
        }
        else
        {
            HlifePhysical hlifePhysical = physicalMapper.getByPrimaryKey(projectId);
            physicalList = new ArrayList<>();
            physicalList.add(hlifePhysical);
        }

        if (physicalList.isEmpty()) {
            log.info("not found any physical, org:" + sourceOrg);
            return;
        }

        for (HlifePhysical physical : physicalList) {

            log.info("copy physical:" + physical.getId());

            //是否存在
            Map<String,Object> params = new HashMap<>();
            params.put("orgId",targetOrg);
            params.put("name",physical.getName());
            HlifePhysical hlifePhysical = physicalMapper.getByMapParams(params);
            if(null==hlifePhysical) {
                hlifePhysical = new HlifePhysical();
                BeanUtils.copyProperties(physical,hlifePhysical);
                hlifePhysical.setOrgId(targetOrg);
                physicalMapper.insert(hlifePhysical);
            }
            else
            {
                hlifePhysical.setOrgId(targetOrg);
                hlifePhysical.setName(physical.getName());
                hlifePhysical.setReadStatus(physical.getReadStatus());
                hlifePhysical.setUnit(physical.getUnit());
                physicalMapper.update(hlifePhysical);
            }

            long physicalId = physical.getId();

            //查询关联考察功能点
            Map<String,Object> physicalTargetParams = new HashMap<>();
            physicalTargetParams.put("physicalId",physicalId);
            List<HlifePhysicalTarget> hlifePhysicalTargetList = physicalTargetMapper.getListByMapParams(physicalTargetParams);
            for(HlifePhysicalTarget physicalTarget : hlifePhysicalTargetList)
            {
                //是否存在
                Map<String,Object> targetParams = new HashMap<>();
                targetParams.put("physicalId",hlifePhysical.getId());
                targetParams.put("targetId",physicalTarget.getTargetId());
                HlifePhysicalTarget hlifePhysicalTarget = physicalTargetMapper.getByMapParams(targetParams);
                if(null==hlifePhysicalTarget) {
                    hlifePhysicalTarget = new HlifePhysicalTarget();
                    hlifePhysicalTarget.setPhysicalId(hlifePhysical.getId());
                    hlifePhysicalTarget.setTargetId(physicalTarget.getTargetId());
                    hlifePhysicalTarget.setStatus((byte)1);
                    physicalTargetMapper.insert(hlifePhysicalTarget);
                }
            }

            //查询原规则列表
            List<HlifePhysicalRule> rules = physicalRuleMapper.getPhysicalRuleListByPhysical(physicalId);
            if (rules == null || rules.size() <= 0) {
                log.info(" not found any rule");
                continue;
            }

            for (HlifePhysicalRule rule : rules) {

                //是否存在
                Map<String,Object> ruleParams = new HashMap<>();
                ruleParams.put("orgId",targetOrg);
                ruleParams.put("physicalId",hlifePhysical.getId());//查询新增的项目
                ruleParams.put("gradeId",rule.getGradeId());//年级
                ruleParams.put("sex",rule.getSex());//性别
                HlifePhysicalRule hlifePhysicalRule = physicalRuleMapper.getByMapParams(ruleParams);
                if(null==hlifePhysicalRule) {
                    hlifePhysicalRule = new HlifePhysicalRule();
                    hlifePhysicalRule.setPhysicalId(hlifePhysical.getId());
                    hlifePhysicalRule.setOrgId(targetOrg);
                    hlifePhysicalRule.setGradeId(rule.getGradeId());
                    hlifePhysicalRule.setGradeName(rule.getGradeName());
                    hlifePhysicalRule.setRuleType(rule.getRuleType());
                    hlifePhysicalRule.setSex(rule.getSex());
                    hlifePhysicalRule.setWeight(rule.getWeight());
                    physicalRuleMapper.insert(hlifePhysicalRule);
                }
                else
                {
                    hlifePhysicalRule.setGradeId(rule.getGradeId());
                    hlifePhysicalRule.setGradeName(rule.getGradeName());
                    hlifePhysicalRule.setRuleType(rule.getRuleType());
                    hlifePhysicalRule.setSex(rule.getSex());
                    hlifePhysicalRule.setWeight(rule.getWeight());
                    physicalRuleMapper.update(hlifePhysicalRule);
                }

                log.info("copy rule(id:" + rule.getId() + ", grade:" + rule.getGradeId() + ")");

                Long ruleId = rule.getId();//原规则ID
                Long physicalRuleId = hlifePhysicalRule.getId();
                log.info("原规则ID:{} 现规则ID:{}",ruleId,physicalRuleId);
                //查询原规则项列表
                List<HlifePhysicalRuleItem> items = physicalRuleItemMapper.getItemListByRule(ruleId);
                if (items != null && items.size() > 0) {
                    for (HlifePhysicalRuleItem item : items) {

                        //是否存在
                        Map<String,Object> ruleItemParams = new HashMap<>();
                        ruleItemParams.put("ruleId",physicalRuleId);
                        ruleItemParams.put("name",item.getName());
                        ruleItemParams.put("score",item.getScore());
                        HlifePhysicalRuleItem hlifePhysicalRuleItem = physicalRuleItemMapper.getByMapParams(ruleItemParams);
                        if(null==hlifePhysicalRuleItem) {
                            hlifePhysicalRuleItem = new HlifePhysicalRuleItem();
                            BeanUtils.copyProperties(item,hlifePhysicalRuleItem);
                            hlifePhysicalRuleItem.setRuleId(physicalRuleId);
                            physicalRuleItemMapper.insert(hlifePhysicalRuleItem);
                        }
                        else
                        {
                            BeanUtils.copyProperties(item,hlifePhysicalRuleItem,"id");
                            hlifePhysicalRuleItem.setRuleId(physicalRuleId);
                            physicalRuleItemMapper.update(hlifePhysicalRuleItem);
                        }
                    }
                    log.info("copy " + items.size() + " item(s)");
                }

                //查询原规则加分项列表
                List<HlifePhysicalRulePluses> pluses = physicalRulePlusesMapper.getPlusListByRule(ruleId);
                if (pluses != null && pluses.size() > 0) {
                    for (HlifePhysicalRulePluses plus : pluses) {

                        //是否存在
                        Map<String,Object> rulePlusesParams = new HashMap<>();
                        rulePlusesParams.put("ruleId",physicalRuleId);
                        rulePlusesParams.put("score",plus.getScore());
                        HlifePhysicalRulePluses hlifePhysicalRulePluses = physicalRulePlusesMapper.getByMapParams(rulePlusesParams);
                        if(null==hlifePhysicalRulePluses) {
                            hlifePhysicalRulePluses = new HlifePhysicalRulePluses();
                            BeanUtils.copyProperties(plus,hlifePhysicalRulePluses);
                            hlifePhysicalRulePluses.setRuleId(physicalRuleId);
                            physicalRulePlusesMapper.insert(hlifePhysicalRulePluses);
                        }
                        else
                        {
                            BeanUtils.copyProperties(plus,hlifePhysicalRulePluses,"id");
                            hlifePhysicalRulePluses.setRuleId(physicalRuleId);
                            physicalRulePlusesMapper.update(hlifePhysicalRulePluses);
                        }
                    }
                    log.info("copy " + pluses.size() + " plus(s)");
                }
            }
        }
    }


    /**
     * 插入年级规则和得分规则以及加分规则
     * @param rules
     * @param physical
     */
    private void insertRules(List<PhysicalRuleDto> rules, HlifePhysical physical) {
        String unit = physical.getUnit();

        for (PhysicalRuleDto ruleDto : rules) {

            HlifePhysicalRule rule = new HlifePhysicalRule();
            rule.setPhysicalId(physical.getId());
            rule.setOrgId(physical.getOrgId());
            rule.setGradeId(ruleDto.getGradeId());           //年级id
            rule.setGradeName(ruleDto.getGradeName());       //年级名称
            rule.setSex(ruleDto.getSex());                   //性别
            rule.setRuleType(ruleDto.getRuleType());         //排序规则
            rule.setWeight(ruleDto.getWeight());
            log.info("rule(grade:" + rule.getGradeId() + ", sex:" + rule.getSex() + ", ruleType:" + rule.getRuleType() + ", weight:" + rule.getWeight() + ")");
            physicalRuleMapper.insert(rule);
            //体检规则列表
            List<PhysicalRuleItemDto> itemsDtos = ruleDto.getItemDtoList();
            if (itemsDtos == null || itemsDtos.size() <= 0) {
                continue;
            }

            double base = rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue() ? 99999D : 0;

            Double baseMax = null;

            String link = rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue() ? " > n >= " : " >= n > ";

            for (PhysicalRuleItemDto itemDto : itemsDtos) {
                HlifePhysicalRuleItem item = new HlifePhysicalRuleItem();
                item.setRuleId(rule.getId());
                item.setScore(itemDto.getScore());                  //分数
                item.setScoreValue(itemDto.getScoreValue());
                item.setName(itemDto.getName());                    //级别名称
                item.setComment(itemDto.getComment());              //评论
//                double value = SportsUtils.translate(unit, itemDto.getScoreValue());
                double value = Double.parseDouble(item.getScoreValue());
                if (baseMax == null) {
                    baseMax = value;
                }
                if (rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue()) {
                    item.setMax(base);
                    item.setMin(value);
                } else {
                    item.setMax(value);
                    item.setMin(base);
                }
                base = value;
                log.info("item(" + item.getScoreValue() + ") " + item.getMax() + link + item.getMin() + " : " + item.getScore());
                if (item.getMax() < item.getMin()) {                  //max < min
                	log.error("error(" + item.getScoreValue() + ") " + item.getMax() + link + item.getMin() + " : " + item.getScore());
                    throw new RuntimeException(item.getMax() + link + item.getMin());
                }
                physicalRuleItemMapper.insert(item);
            }

            List<PhysicalRulePlusesDto> pluses = ruleDto.getPlusesList();
            if (pluses == null || pluses.size() <= 0) {
                continue;
            }

            log.info("baseMax:" + baseMax);

            base = rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue() ? 99999D : 0;

            for (PhysicalRulePlusesDto plusDto : pluses) {

                String bonusValue = plusDto.getBonusValue();

                if (bonusValue == null || "".equals(bonusValue)) {
                    continue;
                }
                HlifePhysicalRulePluses plus = new HlifePhysicalRulePluses();
                plus.setRuleId(rule.getId());
                plus.setBonusValue(bonusValue);                              //额外成绩
                plus.setScore(plusDto.getScore());                           //额外分数

                bonusValue = bonusValue.replace("+", "").replace("-", "");
                double value = SportsUtils.translate(unit, bonusValue);
                if (rule.getRuleType().intValue() == SportsRuleTypeEnum.DESC.getValue()) {
//                    value = baseMax + value;
                    plus.setMax(base);
                    plus.setMin(value);
                } else {
//                    value = baseMax - value;
                    plus.setMax(value);
                    plus.setMin(base);
                }
                base = value;
                log.info("   plus(" + plus.getBonusValue() + ") " + plus.getMax() + link + plus.getMin() + " : " + plus.getScore());

                if (plus.getMax() < plus.getMin()) {                  //max < min
                    throw new RuntimeException(plus.getMax() + link + plus.getMin());
                }
                physicalRulePlusesMapper.insert(plus);
            }
        }
    }

	@Override
	public ResultDTO<Map<String, Object>> saveData(UserDto userDto, Long orgId, List<Object[]> data,
			Map<String,Object> map, int currentRow) {
		
		  if (null == orgId || CollectionUtils.isEmpty(data)) {
	            return new ResultDTO<>(ErrorCode.PARAM_MISSING);
	        }
	        //定义一个Map,用于存储每条数据,什么原因而失败
            List<GradeDto> gradeDtos = settingService.getOrgGradeList(3);

            log.info("saveData:data {}:",JsonUtil.objectToJson(data));
	        for (Object[] proj : data) {
	        	if(proj ==null || StringUtil.isEmpty(proj[0].toString())){
                    return new ResultDTO<>(false, "200", "项目序号不能为空");
                }
	        	PhysicalDto physicalDto  = new PhysicalDto();
	        	physicalDto.setOrgId(orgId);
	        	physicalDto.setName(proj[1].toString());
	        	if(proj[2].toString().endsWith("国家标准")){
	        		physicalDto.setMarkType((byte)1);
	        	}
	        	if(proj[2].toString().endsWith("地方标准")){
	        		physicalDto.setMarkType((byte)2);
	        		String province = proj[6].toString().trim();
	        		String city = proj[7].toString().trim();

	        		if(StringUtil.isEmpty(province) || StringUtil.isEmpty(city)){
	        			return new ResultDTO<>(ErrorCode.PARAM_MISSING);
	        		}
                    ResultDTO<DistrictDto> resultDTO = basicFeignService.findDistrict(province,1);
	        		if (resultDTO.isSuccess()){
	        		    physicalDto.setProvince(province);
	        		    physicalDto.setProvinceId(resultDTO.getData().getCode());
                    }else{
	        		    String errorMsg = physicalDto.getName() + ": " + province +"-获取失败";
                        return new ResultDTO<>(false, "200", errorMsg);
                    }
                    ResultDTO<DistrictDto> resultDTO1 = basicFeignService.findDistrict(city,2);
	        		if (resultDTO1.isSuccess()){
	        		    physicalDto.setCity(city);
	        		    physicalDto.setCityId(resultDTO1.getData().getCode());
                    }else{
                        String errorMsg = physicalDto.getName() + ": " + city +"-获取失败";
                        return new ResultDTO<>(false, "200", errorMsg);
                    }
	        	}
	        	
	        	physicalDto.setProjectKind(ExcelFieldUtil.checkProject(proj[3].toString()));
	        	
	        	physicalDto.setModelType(ExcelFieldUtil.checkModel(proj[4].toString()));
	        	
	        	List<Object[]>  ruleData = (List<Object[]>)map.get("ruleData");
	        	
	        	if(ruleData != null && ruleData.size()>0){
	        		ruleData = ruleData.subList(1, ruleData.size());
	        	}
	        	
	        	
	        	List<Object[]>  ruleDetailData = (List<Object[]>)map.get("ruleDetailData");
	        	
	        	if(ruleDetailData != null && ruleDetailData.size()>0){
	        		ruleDetailData = ruleDetailData.subList(1, ruleDetailData.size());
	        	}
	        	
	        	 
	             
	            List<Object[]>  rulePlusData = (List<Object[]>)map.get("rulePlusData");
	            
	            if(rulePlusData != null && rulePlusData.size()>0){
	            	rulePlusData = rulePlusData.subList(1, rulePlusData.size());
	        	}
	            
	             
	        	
	        	List<PhysicalRuleDto>  ruleList = new ArrayList<>();
	        	
	        	for(Object[] rule : ruleData){
	        		
	        		if(Double.valueOf(rule[4].toString()).equals(Double.valueOf(proj[0].toString()))){
	        			
	        			PhysicalRuleDto  physicalRuleDto  = new PhysicalRuleDto();
	        			
//	        			ResultDTO<GradeDto> gradeDto =	basicFeignService.getGradeByName(orgId, rule[1].toString());
                        String grade = rule[1].toString();
                        Optional<GradeDto> optionalGradeDto = gradeDtos.stream().filter(item -> item.getGradeName().equals(grade)).findFirst();
                        if (optionalGradeDto.isPresent()){
                            physicalRuleDto.setGradeId(optionalGradeDto.get().getId());
                            physicalRuleDto.setGradeName(grade);
                        }

	        			if(rule[2].toString().equals("男")){
	        				physicalRuleDto.setSex((byte)1);
	        				
	        			}else{
	        				physicalRuleDto.setSex((byte)2);
	        			}
	        			
	        			if(rule[3].toString().trim().equals("成绩数值越小得分越高")){
	        				physicalRuleDto.setRuleType((byte)1);
	        			}else{
	        				physicalRuleDto.setRuleType((byte)2);
	        			}
	        			
	        			ruleList.add(physicalRuleDto);
	        			
	        			
	        			List<PhysicalRuleItemDto>  ruleItemList = new ArrayList<>();
	        			
	        			 List<PhysicalRulePlusesDto>  rulePluesList = new  ArrayList<>();
		        		
		        		for(Object[] ruleDetail :ruleDetailData){
		        			
		        			if(Double.valueOf(ruleDetail[4].toString()).equals(Double.valueOf(rule[0].toString()))){
		        				
		        				PhysicalRuleItemDto physicalRuleItemDto = new PhysicalRuleItemDto();
		        				
		        				physicalRuleItemDto.setScore(Double.valueOf(ruleDetail[0].toString()));
		        				physicalRuleItemDto.setScoreValue(ruleDetail[1].toString());
		        				switch (ruleDetail[2].toString().trim()){
		        				    case "优秀":physicalRuleItemDto.setName("1");
                                    break;
		        				    case "良好":physicalRuleItemDto.setName("2");
                                    break;
		        				    case "及格":physicalRuleItemDto.setName("3");
                                    break;
		        				    case "不及格":physicalRuleItemDto.setName("4");
                                    break;
                                }

		        				ruleItemList.add(physicalRuleItemDto);
		        				
		        			}
		        			
		        			
		        		}
		        		
		        		
		        		for(Object[] rulePlus :rulePlusData){
		        			
		        			if(Double.valueOf(rulePlus[2].toString()).equals(Double.valueOf(rule[0].toString()))){
		        				
		        				PhysicalRulePlusesDto  physicalRulePlusesDto  = new PhysicalRulePlusesDto();
		        				
		        				physicalRulePlusesDto.setScore(Double.valueOf(rulePlus[0].toString()));
		        				
		        				physicalRulePlusesDto.setBonusValue(rulePlus[1].toString());
		        				
		        				rulePluesList.add(physicalRulePlusesDto);
		        				
		        			}
		        			
		        			
		        		}
		        		
	        			
		        		if(null != ruleItemList && ruleItemList.size()>0){
		        			
		        			physicalRuleDto.setItemDtoList(ruleItemList);
		        		}
		        		
		        		
		        		if(null != rulePluesList && rulePluesList.size()>0){
		        			
		        			physicalRuleDto.setPlusesList(rulePluesList);
		        		}
		        		
		        		
	        			
	        		}
	        		
	        		
	        	}

	        	physicalDto.setRuleList(ruleList);

	        	ResultDTO resultDTO = addPhysical(physicalDto);
	        	if (!resultDTO.isSuccess()){
                    return resultDTO;
                }
	            
	            currentRow++;
	        }
	        //saveImportLog(userDto, newOrgId, importOkList, importFailList);
	        return new ResultDTO();
	}
}